<template>
  <div class="main">
    <!-- 数据查询区：表单 -->
    <el-form ref="queryRef" :model="queryParams" :inline="true">
      <el-form-item label="编码" prop="productSn">
        <el-input
          v-model="queryParams.productSn"
          placeholder="请输入编码"
          clearable
          style="width: 200px"
          @keyup.enter="handleQuery"
        />
      </el-form-item>
      <el-form-item label="名称" prop="productName">
        <el-input
          v-model="queryParams.productName"
          placeholder="请输入名称"
          clearable
          style="width: 200px"
          @keyup.enter="handleQuery"
        />
      </el-form-item>
      <el-form-item label="类别" prop="categoryId">
        <el-select
          v-model="queryParams.categoryId"
          style="width: 200px"
          placeholder="请选择类别"
        >
          <el-option
            v-for="item in categoryOptions"
            :key="item.categoryId"
            :label="item.categoryName"
            :value="item.categoryId"
          />
        </el-select>
      </el-form-item>
      <el-form-item>
        <el-button type="primary" icon="Search" @click="handleQuery"
          >搜索</el-button
        >
        <el-button icon="Refresh" @click="resetQuery(queryRef)">重置</el-button>
      </el-form-item>
    </el-form>

    <!-- 数据操作区：按钮 -->
    <el-row :gutter="10">
      <el-col :span="1.5">
        <el-button type="primary" plain icon="Plus" @click="handleAdd"
          >新增</el-button
        >
      </el-col>
      <el-col :span="1.5">
        <el-button
          type="success"
          plain
          icon="Edit"
          :disabled="!single"
          @click="handleUpdate"
          >修改</el-button
        >
      </el-col>
      <el-col :span="1.5">
        <el-button
          type="danger"
          plain
          icon="Delete"
          :disabled="!multiple"
          @click="handleDeleteBatch"
          >批量删除</el-button
        >
      </el-col>
    </el-row>
    <br />
    <!-- 数据展示区：表格 -->
    <el-table
      v-loading="loading"
      :data="dataList"
      @selection-change="handleSelectionChange"
    >
      <el-table-column type="selection" width="55" align="center" />
      <el-table-column label="ID" align="center" width="80" prop="productId" />
      <el-table-column
        label="编码"
        align="center"
        width="150"
        prop="productSn"
      />
      <el-table-column label="名称" align="center" prop="productName" />
      <el-table-column
        label="类别ID"
        align="center"
        width="150"
        prop="category.categoryId"
      />
      <el-table-column
        label="类别"
        align="center"
        width="150"
        prop="category.categoryName"
      />
      <el-table-column label="价格" align="center" width="150" prop="price" />
      <el-table-column
        label="操作"
        align="center"
        class-name="small-padding fixed-width"
      >
        <template #default="scope">
          <el-button
            link
            type="primary"
            icon="Edit"
            size="small"
            @click="handleUpdate(scope.row)"
            >修改</el-button
          >
          <el-button
            link
            type="primary"
            icon="Delete"
            size="small"
            @click="handleDelete(scope.row)"
            >删除</el-button
          >
          <el-button
            link
            type="primary"
            icon="View"
            size="small"
            @click="handleView(scope.row)"
            >查看</el-button
          >
        </template>
      </el-table-column>
    </el-table>

    <!-- 数据展示区：分页加载 -->
    <el-pagination
      v-model:current-page="queryParams.pageNum"
      v-model:page-size="queryParams.pageSize"
      style="margin-top: 20px"
      :page-sizes="[5, 10, 20, 30]"
      layout="total, sizes, prev, pager, next, jumper"
      :total="total"
      @size-change="handleSizeChange"
      @current-change="handleCurrentChange"
    />

    <!-- 数据编辑区：新增/修改对话框 默认不显示 -->
    <el-dialog v-model="open" :title="title" width="500px" append-to-body>
      <el-form ref="formRef" :model="form" :rules="rules" label-width="80px">
        <el-form-item label="编码" prop="productSn">
          <el-input v-model="form.productSn" placeholder="请输入编码" />
        </el-form-item>
        <el-form-item label="名称" prop="productName">
          <el-input v-model="form.productName" placeholder="请输入名称" />
        </el-form-item>
        <el-form-item label="类别" prop="categoryId">
          <el-select v-model="form.categoryId" placeholder="请选择类别">
            <el-option
              v-for="item in categoryOptions"
              :key="item.categoryId"
              :label="item.categoryName"
              :value="item.categoryId"
            />
          </el-select>
        </el-form-item>
        <el-form-item label="价格" prop="price">
          <el-input v-model="form.price" placeholder="请输入价格" />
        </el-form-item>
      </el-form>
      <template #footer>
        <div class="dialog-footer">
          <el-button type="primary" @click="submitForm(formRef)"
            >确 定</el-button
          >
          <el-button
            v-show="form.productId === undefined"
            @click="resetForm(formRef)"
            >重 置</el-button
          >
          <el-button @click="cancel()">取 消</el-button>
        </div>
      </template>
    </el-dialog>

    <el-drawer v-model="drawer" title="产品信息" :with-header="false">
      <el-descriptions :title="productTitle" :column="2" border>
        <el-descriptions-item label="编码">{{
          product.productSn
        }}</el-descriptions-item>
        <el-descriptions-item label="名称">{{
          product.productName
        }}</el-descriptions-item>
        <el-descriptions-item label="价格">{{
          product.price
        }}</el-descriptions-item>
        <el-descriptions-item label="类别">{{
          product.category.categoryName
        }}</el-descriptions-item>
      </el-descriptions>
    </el-drawer>
  </div>
</template>

<script lang="ts" setup>
/** ------------------全局导入区-------------------- */
import { ref, reactive, toRef, onMounted } from "vue";
import type { FormInstance, FormRules } from "element-plus";
import { ElMessage, ElMessageBox } from "element-plus";
import { listAllCategory } from "@/api/category";
import {
  listProductByPage,
  getProductById,
  addProduct,
  updateProduct,
  deleteProduct,
  deleteProductBatch
} from "@/api/product";
import type {
  CategoryDTO,
  QueryParams,
  ProductDTO,
  ProductForm
} from "@/api/product";

onMounted(() => {
  // 挂载后加载数据
  getList();
  getCategoryOptions();
});

/** ------------------数据查询区——表单-------------------- */
// 表单实例
const queryRef = ref<FormInstance>();

// 类别下拉框
const categoryOptions = ref<CategoryDTO[]>([]);

function getCategoryOptions() {
  listAllCategory().then(response => {
    categoryOptions.value = response.data;
  });
}

// 查询
const query = reactive<QueryParams>({
  pageNum: 1,
  pageSize: 5,
  productSn: undefined,
  productName: undefined,
  categoryId: undefined
});
const queryParams = toRef(query);
// 数据查询区--> 查询按钮
function handleQuery() {
  queryParams.value.pageNum = 1;
  getList();
}
// 数据查询区--> 重置按钮
const resetQuery = (formEl: FormInstance | undefined) => {
  if (!formEl) return;
  formEl.resetFields();
  getList();
};

/** ------------------数据展示区——表格-------------------- */

// 数据列表
const loading = ref<boolean>(false); // table数据加载遮罩
const total = ref<number>(0); // table数据总数
const tableData = reactive<ProductDTO[]>([]); // table数据
const dataList = toRef(tableData);

// 数据展示区--> 数据加载
function getList() {
  loading.value = true;
  /** 调用后端分页查询接口 */
  listProductByPage(queryParams.value).then(response => {
    dataList.value = response.data.list;
    total.value = response.data.total;
    loading.value = false;
  });
}

/** ------------------数据展示区：数据选择-------------------- */

const ids = ref<number[]>([]); // 表单勾选的id
const single = ref<boolean>(false); // 勾选1个
const multiple = ref<boolean>(false); // 勾选多个

// 数据展示区--> 勾选数据
function handleSelectionChange(selection: ProductDTO[]) {
  ids.value = selection.map((item: ProductDTO) => item.productId);
  single.value = selection.length == 1;
  multiple.value = selection.length >= 1;
}

/** ------------------数据展示区：分页加载-------------------- */
// 分页--> 修改每页数据数（5｜10｜20｜30）
function handleSizeChange(val: number) {
  queryParams.value.pageSize = val;
  getList();
}

//分页--> 修改当前页
function handleCurrentChange(val: number) {
  queryParams.value.pageNum = val;
  getList();
}

/** ------------------数据编辑区——对话框+表单-------------------- */
// 表单数据
const formRef = ref<FormInstance>();

const formData = reactive<ProductForm>({
  productId: undefined,
  productSn: undefined,
  productName: undefined,
  categoryId: undefined,
  price: 0.0
});
const form = toRef(formData);
const rules = reactive<FormRules<ProductForm>>({
  // 表单验证规则
  productSn: [
    { required: true, message: "编码不能为空", trigger: "blur" },
    { min: 4, max: 10, message: "长度在4-10 个字符", trigger: "blur" }
  ],
  productName: [{ required: true, message: "名称不能为空", trigger: "blur" }],
  categoryId: [{ required: true, message: "类别不能为空", trigger: "blur" }],
  price: [
    {
      pattern: /(^[1-9]\d*(\.\d{1,2})?$)|(^0(\.\d{1,2})?$)/,
      message: "价格格式不正确, 参考20.50",
      trigger: "blur"
    }
  ]
});

// 对话框数据
const title = ref(""); // 对话框标题
const open = ref(false); //对话框打开

// 数据编辑区-->提交按钮
const submitForm = async (formEl: FormInstance | undefined) => {
  if (!formEl) return;
  await formEl.validate((valid, fields) => {
    if (valid) {
      /** 调用后端新增和修改接口 */
      if (form.value.productId != undefined) {
        updateProduct(form.value).then(response => {
          ElMessage({ type: "success", message: "修改数据成功" });
          getList();
          open.value = false;
        });
      } else {
        addProduct(form.value).then(response => {
          ElMessage({ type: "success", message: "新增数据成功" });
          getList();
          open.value = false;
        });
      }
    } else {
      console.log("表单验证未通过", fields); // 前台会自动提示errors
    }
  });
};

// 数据编辑区-->重置按钮
const resetForm = (formEl: FormInstance | undefined) => {
  if (!formEl) return;
  formEl.resetFields();
};
// 数据编辑区-->取消按钮
function cancel() {
  initForm();
  open.value = false;
}

/** ------------------数据操作区——按钮-------------------- */
// 清空或赋值表单数据
const initForm = () => {
  formRef.value?.resetFields();
};

// 数据操作区--> 新增按钮
function handleAdd() {
  initForm();
  title.value = "新增数据";
  open.value = true;
}

// 数据操作区区--> 修改按钮
function handleUpdate(row: any) {
  initForm();
  const id = row.productId || ids.value[0];
  /** 调用后端id查询接口*/

  getProductById(id).then(response => {
    form.value = response.data;
    title.value = "修改数据[" + id + "]";
    open.value = true;
  });
}

// 数据操作区--> 删除按钮
function handleDelete(row: any) {
  const id = row.productId;
  ElMessageBox.confirm("是否删除编号为" + id + "的数据?", "警告")
    .then(() => {
      return deleteProduct(id);
    })
    .then(() => {
      getList();
      ElMessage({ type: "success", message: "删除成功" });
    })
    .catch(() => {});
}

// 数据操作区--> 批量删除按钮
function handleDeleteBatch() {
  const productIds = ids.value;
  ElMessageBox.confirm("是否批量删除编号为" + productIds + "的数据?", "警告")
    .then(() => {
      return deleteProductBatch(productIds);
    })
    .then(() => {
      getList();
      ElMessage({ type: "success", message: "批量删除成功" });
    })
    .catch(() => {});
}

// 数据操作区-->抽屉查看数据
const drawer = ref<boolean>(false);
const productTitle = ref<string>("");
const product = ref<ProductDTO>({
  productId: 0,
  productSn: "",
  productName: "",
  price: 0,
  categoryId: 0,
  category: { categoryId: 0, categoryName: "" }
});

// 数据操作区--> 查看按钮
function handleView(row: ProductDTO) {
  // product.value = row
  getProductById(row.productId).then(response => {
    product.value = response.data;
    productTitle.value = "查看产品数据[" + row.productId + "]";
  });
  drawer.value = true;
}
</script>

<style scoped></style>
